﻿Imports WiremetModel.Entities.Tracking
Imports WiremetModel.Entities
Imports WiremetModel.Specification.GeneralSpecifications

Public Class frmKontrolaSzukaj

    Private _unitOfWork As UnitOfWork
    Private _zleceniaTrackingDictionary As Dictionary(Of Integer, Zlecenie)

    Private Structure PozycjaZleceniaFilter
        Public numerDrutu As Integer
        Public wymiar As String
    End Structure

    Private Structure ZlecenieFilter
        Public numerZlecenia As String
        Public klientId As Integer
        Public isDateFilterEnabled As Boolean
        Public dateStart As Date
        Public dateEnd As Date
        Public statusZleceniaId As Integer
        Public statusWysylkiId As Integer
    End Structure

    Public Sub New()

        InitializeComponent()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        SetInitialFilter()
        RunFilter()

    End Sub

    Private Sub frmKontrolaSzukaj_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub


    Private Sub RefreshViewData()

        Dim zleceniaTrackingRepository As New Repository(Of Zlecenie)(_unitOfWork)
        Dim klientRepository As New Repository(Of OEM.Klient)(_unitOfWork)
        Dim statusZleceniaRepository As New Repository(Of OEM.Status)(_unitOfWork)
        Dim statusWysylkiRepository As New Repository(Of OEM.StatusWysylki)(_unitOfWork)

        'Dim statusIdSpecification_1 As New StatusIdSpecification(Of PozycjaZlecenia)(1)
        'Dim statusIdSpecification_6 As New StatusIdSpecification(Of PozycjaZlecenia)(6)
        'Dim statusIdSpecification_7 As New StatusIdSpecification(Of PozycjaZlecenia)(7)

        '_pozycjeZlecenTrackingDictionary = pozycjeZleceniaTrackingRepository.GetAllMatching(statusIdSpecification_1.Negate()).ToDictionary(Function(x) x.Id, Function(x) x)
        '.Where(Function(x) x.Status.Id <> 1 AndAlso x.Status.Id <> 6 AndAlso x.Status.Id <> 7).
        _zleceniaTrackingDictionary = zleceniaTrackingRepository.GetAll().ToDictionary(Function(x) x.Id, Function(x) x)
        Dim klientList As IEnumerable(Of OEM.Klient) = klientRepository.GetAll().OrderBy(Function(x) x.NazwaSkrocona)
        Dim statusZleceniaList As IEnumerable(Of OEM.Status) = statusZleceniaRepository.GetAll().OrderBy(Function(x) x.Nazwa)
        Dim statusWysylkiList As IEnumerable(Of OEM.StatusWysylki) = statusWysylkiRepository.GetAll().OrderBy(Function(x) x.Nazwa)

        InitializeFilterComboBox(cmb_Klient, klientList.ToDictionary(Function(x) x.Id, Function(x) x.NazwaSkrocona))
        InitializeFilterComboBox(cmb_StatusZlecenia, statusZleceniaList.ToDictionary(Function(x) x.Id, Function(x) x.Nazwa))
        InitializeFilterComboBox(cmb_StatusWysyłki, statusWysylkiList.ToDictionary(Function(x) x.Id, Function(x) x.Nazwa))

    End Sub

    Private Sub InitializeFilterComboBox(ByRef cmbFilter As ComboBox, ByVal data As Dictionary(Of Integer, String))
        
        cmbFilter.DataSource = New BindingSource(data, Nothing)
        cmbFilter.DisplayMember = "Value"
        cmbFilter.ValueMember = "Key"
        cmbFilter.AutoCompleteCustomSource.Clear()
        cmbFilter.AutoCompleteCustomSource.AddRange(data.Values.OrderBy(Function(x) x).ToArray())
        cmbFilter.SelectedIndex = -1

    End Sub

    Private Sub SetInitialFilter()

        cmb_StatusZlecenia.SelectedValue = 4

    End Sub

    Private Sub RefreshZleceniaTable(ByVal pozycjeZlecenList As IEnumerable(Of PozycjaZlecenia))

        dgv_PozycjeZlecenia.Rows.Clear()

        For Each pozycjaZlecenia As PozycjaZlecenia In pozycjeZlecenList

            Dim index As Integer = dgv_PozycjeZlecenia.Rows.Add(
                pozycjaZlecenia.Id,
                pozycjaZlecenia.Zlecenie.Numer,
                pozycjaZlecenia.Zlecenie.Klient.NazwaSkrocona,
                pozycjaZlecenia.Zlecenie.Termin.ToShortDateString(),
                pozycjaZlecenia.Gatunek.NazwaAng,
                pozycjaZlecenia.Wymiar,
                pozycjaZlecenia.Ilosc,
                pozycjaZlecenia.Zlecenie.Status.Nazwa,
                pozycjaZlecenia.Zlecenie.ZlecenieOEM.StatusWysylki.Nazwa)


            If pozycjaZlecenia.Schematy.Values.SelectMany(Function(x) x.PozycjeSchematu.Values).SelectMany(Function(x) x.Druty.Values).Any(Function(x) x.Opcja.Id = 4) Then
                dgv_PozycjeZlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Green400
            Else
                Select Case CType(pozycjaZlecenia.Zlecenie.Termin, Date).ToShortDateString
                    Case CStr(Date.Today)
                        dgv_PozycjeZlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Yellow500
                    Case CStr(DateSerial(Today.Year, Today.Month, Today.Day + 1))
                        dgv_PozycjeZlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Yellow500
                    Case Is < CStr(DateSerial(Today.Year, Today.Month, Today.Day))
                        dgv_PozycjeZlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Red350
                End Select
            End If
        Next
    End Sub



#Region "Filter"
    Private Function GetZlecenieFilter() As ZlecenieFilter

        Return New ZlecenieFilter With {
            .numerZlecenia = tb_NumerZlecenia.Text.Trim(),
            .klientId = CInt(cmb_Klient.SelectedValue),
            .isDateFilterEnabled = cb_DataRealizacji.Checked,
            .dateStart = dtp_DataRealizacjiOd.Value.Date,
            .dateEnd = dtp_DataRealizacjiDo.Value.Date,
            .statusZleceniaId = CInt(cmb_StatusZlecenia.SelectedValue),
            .statusWysylkiId = CInt(cmb_StatusWysyłki.SelectedValue)
        }
    End Function


    Private Function GetPozycjaZleceniaFilter() As PozycjaZleceniaFilter
        Dim numerDrutu As Integer = 0
        Integer.TryParse(tb_NumerDrutu.Text.Trim(), numerDrutu)

        Return New PozycjaZleceniaFilter With {
            .wymiar = tb_FiltrWymiar.Text.Trim(),
            .numerDrutu = numerDrutu
        }
    End Function

    Private Function IsZlecenieSatisfiedByFilter(ByVal zlecenie As Zlecenie, ByVal filter As ZlecenieFilter) As Boolean

        Return zlecenie.Numer.StartsWith(filter.numerZlecenia, StringComparison.CurrentCultureIgnoreCase) AndAlso
               (filter.klientId = 0 OrElse zlecenie.Klient.Id = filter.klientId) AndAlso
               (Not filter.isDateFilterEnabled OrElse (zlecenie.Termin >= filter.dateStart AndAlso zlecenie.Termin <= filter.dateEnd)) AndAlso
               (filter.statusZleceniaId = 0 OrElse zlecenie.Status.Id = filter.statusZleceniaId) AndAlso
               (filter.statusWysylkiId = 0 OrElse zlecenie.ZlecenieOEM.StatusWysylki.Id = filter.statusWysylkiId)
    End Function

    Private Function IsPozycjaZleceniaSatisfiedByFilter(ByVal pozycjaZlecenia As PozycjaZlecenia, ByVal filter As PozycjaZleceniaFilter) As Boolean

        Return (filter.numerDrutu = 0 OrElse pozycjaZlecenia.Schematy.Values.SelectMany(Function(x) x.PozycjeSchematu.Values).SelectMany(Function(x) x.Druty.Values).Any(Function(x) x.Id = filter.numerDrutu AndAlso x.Opcja.Id = 4)) AndAlso
               (filter.wymiar = String.Empty OrElse pozycjaZlecenia.Wymiar.StartsWith(filter.wymiar, StringComparison.CurrentCultureIgnoreCase))

    End Function


    Private Sub RunFilter()

        Dim zlecenieFilter As ZlecenieFilter = GetZlecenieFilter()
        Dim pozycjaZleceniaFilter As PozycjaZleceniaFilter = GetPozycjaZleceniaFilter()

        Dim filteredPozycjeZlecen As New List(Of PozycjaZlecenia)

        For Each zlecenie As Zlecenie In _zleceniaTrackingDictionary.Values
            If IsZlecenieSatisfiedByFilter(zlecenie, zlecenieFilter) Then
                For Each pozycjaZlecenia As PozycjaZlecenia In zlecenie.PozycjeZlecenia.Values
                    If IsPozycjaZleceniaSatisfiedByFilter(pozycjaZlecenia, pozycjaZleceniaFilter) Then
                        filteredPozycjeZlecen.Add(pozycjaZlecenia)
                    End If
                Next
            End If
        Next

        RefreshZleceniaTable(filteredPozycjeZlecen.OrderByDescending(Function(x) x.Zlecenie.Termin))

        ComboBoxCleanupWhenNoValueSelected(cmb_Klient)
        ComboBoxCleanupWhenNoValueSelected(cmb_StatusZlecenia)
        ComboBoxCleanupWhenNoValueSelected(cmb_StatusWysyłki)

    End Sub


    Private Sub ComboBoxCleanupWhenNoValueSelected(ByRef comboBox As ComboBox)
        If comboBox.SelectedValue Is Nothing Then
            comboBox.ResetText()
        End If
    End Sub


    Private Sub ClearFilter()

        tb_NumerZlecenia.Text = String.Empty
        cmb_Klient.ResetText()
        cmb_Klient.SelectedIndex = -1
        dtp_DataRealizacjiOd.Value = Now.Date
        dtp_DataRealizacjiDo.Value = Now.Date
        cb_DataRealizacji.Checked = False
        cmb_StatusZlecenia.ResetText()
        cmb_StatusZlecenia.SelectedIndex = -1
        tb_FiltrWymiar.Text = String.Empty
        tb_NumerDrutu.Text = String.Empty

    End Sub
#End Region

    




    Private Sub dgv_PozycjeZlecenia_CellMouseDoubleClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles dgv_PozycjeZlecenia.CellMouseDoubleClick

        Try
            If dgv_PozycjeZlecenia.SelectedRows.Count = 0 Then
                Throw New Exception("Wybierz zlecenie.")
            End If

            Dim biuroCredentials As OEM.Uprawienie = User.Role.GetValueOrDefault("biuro")

            If Not biuroCredentials.WyznModyfikacji AndAlso Not biuroCredentials.WyznOdczytu Then
                Throw New Exception("Nie masz wystarczających uprawnień.")
            End If

            Dim pozycjaZleceniaId As Integer = CInt(dgv_PozycjeZlecenia.SelectedRows(0).Cells("PozycjaZleceniaId").Value)
            Me.Cursor = Cursors.WaitCursor
            'Dim pozycjaZleceniaGosi As New clsInhTrPozycjaZlecenia(pozycjaZleceniaId, New clsDataBase(VAR_CONNECTION_PARAMETERS, VAR_ERROR_HANDLER), True)
            Dim repoPozycjaZlecenia As New Repository(Of PozycjaZlecenia)(_unitOfWork)
            Dim pozycjaZleceniaSpec As New IdSpecification(Of PozycjaZlecenia)(pozycjaZleceniaId)

            Dim kontrolaForm As New frmKontrola(repoPozycjaZlecenia.GetEntityMatching(pozycjaZleceniaSpec))
            kontrolaForm.MdiParent = MdiParent
            kontrolaForm.Show()


        Catch ex As Exception
            MessageBox.Show(ex.Message, "WIREMET", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Me.Cursor = Cursors.Default
        End Try

    End Sub

    Private Sub tb_NumerZlecenia_KeyPress(sender As Object, e As KeyPressEventArgs) Handles tb_NumerZlecenia.KeyPress
        If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
            If tb_NumerZlecenia.Text <> String.Empty And IsNumeric(tb_NumerZlecenia.Text) Then
                RunFilter()
            End If
        End If
    End Sub

    Private Sub tb_NumerDrutu_KeyPress(sender As Object, e As KeyPressEventArgs) Handles tb_NumerDrutu.KeyPress
        If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
            If tb_NumerDrutu.Text <> String.Empty And IsNumeric(tb_NumerDrutu.Text) Then
                RunFilter()
            End If
        End If
    End Sub

    Private Sub dtpDataRealizacji_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dtp_DataRealizacjiDo.ValueChanged, dtp_DataRealizacjiOd.ValueChanged
        cb_DataRealizacji.Checked = True
    End Sub

    Private Sub btn_RunFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_RunFilter.Click
        RunFilter()
    End Sub

    Private Sub btn_Refresh_Click(sender As System.Object, e As System.EventArgs) Handles btn_Refresh.Click
        _unitOfWork.Dispose()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        ClearFilter()
        SetInitialFilter()
        RunFilter()
    End Sub

    Private Sub btn_ClearFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_ClearFilter.Click
        ClearFilter()
        RunFilter()
    End Sub

    Private Sub filterInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tb_NumerZlecenia.KeyDown, cmb_Klient.KeyDown, tb_NumerDrutu.KeyDown, tb_FiltrWymiar.KeyDown, cmb_StatusZlecenia.KeyDown, cmb_StatusWysyłki.KeyDown
        If e.KeyCode = Keys.Enter Then
            RunFilter()
        End If
    End Sub

End Class